package slent.iespana.es.visualizacion;

import slent.iespana.es.visualizacion.DibujadorReaccion;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import com.sun.opengl.util.*;
import es.iespana.slent.reaccion.*;
import java.util.*;
import es.iespana.slent.tablaperiodica.*;
import slent.iespana.es.Quimica.TablaPeriodica.VentanaTablaPeriodica.TablaPeriodicaDefault;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *Esta clase implementa la visualización para la reacción del NH3 (amoniaco) con el agua
 * @author slent
 */
public class ReaccionNH3 implements DibujadorReaccion {

    private GLUT glut = new GLUT();
    private MoleculaNH3 moleculaNH3;
    private MoleculaH2O moleculaH2O;
    private Atomo atomoCentralNH3;
    private Atomo atomoCentralH2O;
    private Reaccion reaccion;
    private List<Molecula> estadoInicial;
    private List<Molecula> estadoFinal;
    private TablaPeriodica tablaPeriodica;
    private double[][] traslations;
    private ArrayList<MoleculaNH3> variasNH3;
    private ArrayList<MoleculaH2O> variasH2O;
    private int numeroMoleculas = 40;
    private boolean detenerDibujo = false;

    public ReaccionNH3() {
        moleculaH2O = new MoleculaH2O();
        moleculaNH3 = new MoleculaNH3();
        moleculaH2O.setGlut(glut);
        moleculaNH3.setGlut(glut);

        variasNH3 = new ArrayList<MoleculaNH3>();
        variasH2O = new ArrayList<MoleculaH2O>();

        for (int i = 0; i < numeroMoleculas / 2; i++) {
            variasNH3.add(new MoleculaNH3());
            variasH2O.add(new MoleculaH2O());
        }
    }

    public GLUT getGlut() {
        return glut;
    }

    public void setGlut(GLUT glut) {
        this.glut = glut;
    }

    public Reaccion getReaccion() {
        return reaccion;
    }

    public void setReaccion(Reaccion reaccion) {
        this.reaccion = reaccion;
    }

    /**
     * Prepara la visualización, encuentra los centros de las moleculas
     */
    public void preparar() {
        estadoInicial = reaccion.getRepresentacionMolecular().getEstadoInicial().getMolecula();
        estadoFinal = reaccion.getRepresentacionMolecular().getEstadoFinal().getMolecula();

        TablaPeriodicaDefault defTabla = new TablaPeriodicaDefault();
        defTabla.cargarTablaPeriodica();
        tablaPeriodica = defTabla.getTablaPeriodica();

        //los atomos centrales son el principio del arbol
        atomoCentralNH3 = estadoInicial.get(0).getAtomo();
        atomoCentralH2O = estadoInicial.get(1).getAtomo();

        moleculaNH3.setAtomoN(atomoCentralNH3);
        moleculaH2O.setAtomoO(atomoCentralH2O);

        for (MoleculaNH3 nh3 : variasNH3) {
            nh3.setGlut(glut);
            nh3.setAtomoN(atomoCentralNH3);
            nh3.preparar();
        }
        for (MoleculaH2O h2o : variasH2O) {
            h2o.setGlut(glut);
            h2o.setAtomoO(atomoCentralH2O);
            h2o.preparar();
        }

        moleculaNH3.preparar();
        moleculaH2O.preparar();

        traslations = new double[numeroMoleculas][3];
        int neg = 1;
        for (int i = 0; i < numeroMoleculas; i++) {
            if (i > ((numeroMoleculas / 2) - 1)) {
                neg = -1;
            }
            traslations[i][0] = neg * (Math.random() * DibujadorMolecula.espaceRatio);
            traslations[i][1] = neg * (Math.random() * DibujadorMolecula.espaceRatio);
            traslations[i][2] = neg * (Math.random() * DibujadorMolecula.espaceRatio);
        }
        System.out.println("traslaciones creadas");
    }

    public void dibujar(GL gl) {
        gl.glPushMatrix();

        gl.glPushMatrix();
        gl.glColor3d(1, 0, 0);
//        gl.glBegin(GL.GL_LINES);
//        {
//            gl.glVertex3d(0, 0, 0);
//            gl.glVertex3d(1, 0, 0);
//            gl.glColor3d(0, 0, 1);
//            gl.glVertex3d(0, 0, 0);
//            gl.glVertex3d(0, 1, 0);
//            gl.glColor3d(0, 1, 0);
//            gl.glVertex3d(0, 0, 0);
//            gl.glVertex3d(0, 0, 1);
//        }
//        gl.glEnd();
        gl.glPopMatrix();

        gl.glPushMatrix();
        gl.glTranslated(-1, 0, 0);
//        moleculaNH3.setPosicionInicial(new Posicion(-1, 0, 0));
//        moleculaNH3.dibujar(gl);
        gl.glPopMatrix();
        gl.glTranslated(1, 0, 0);
//        moleculaH2O.setPosicionInicial(new Posicion(1, 0, 0));
//        moleculaH2O.dibujar(gl);
        gl.glPopMatrix();

        for (int i = 0; i < numeroMoleculas/2; i++) {
            gl.glPushMatrix();
            gl.glTranslated(traslations[i][0], traslations[i][1], traslations[i][2]);
            variasNH3.get(i).setPosicionInicial(new Posicion(traslations[i][0], traslations[i][1], traslations[i][2]));
            variasNH3.get(i).dibujar(gl);
            gl.glPopMatrix();
            gl.glPushMatrix();
            gl.glTranslated(traslations[i + (numeroMoleculas/2)][0], traslations[i + (numeroMoleculas/2)][1], traslations[i + (numeroMoleculas/2)][2]);
            variasH2O.get(i).setPosicionInicial(
                    new Posicion(traslations[i + (numeroMoleculas/2)][0], traslations[i + (numeroMoleculas/2)][1], traslations[i + (numeroMoleculas/2)][2]));
            variasH2O.get(i).dibujar(gl);
            gl.glPopMatrix();
        }
        if (revisarColisiones(variasNH3, variasH2O)) {
        }
        revisarColisionesNH3(variasNH3);
        revisarColisionesH2O(variasH2O);

    }

    /**
     * Esta función se encarga de revisar si existen colisiones entre alguna molecula dentro de
     * moleculasA con algun otro de moleculasB
     * @param moleculasA
     * @param moleculasB
     */
    public static boolean revisarColisiones(ArrayList<MoleculaNH3> moleculasA, ArrayList<MoleculaH2O> moleculasB) {
        boolean existeColision = false;
        for (DibujadorMolecula moleculaA : moleculasA) {
            for (DibujadorMolecula moleculaB : moleculasB) {
                if (Posicion.checkColision(moleculaA.getPosicionInicial(), moleculaB.getPosicionInicial())) {
                    moleculaA.reaccionar();
                    moleculaB.reaccionar();
                    existeColision = true;
                }

            }
        }
        return existeColision;
    }

    public static void revisarColisionesNH3(ArrayList<MoleculaNH3> moleculasA){
        for (DibujadorMolecula moleculaA : moleculasA) {
            for (DibujadorMolecula moleculaB : moleculasA) {
                if (Posicion.checkColision(moleculaA.getPosicionInicial(), moleculaB.getPosicionInicial())) {
                    if(moleculaA!=moleculaB)
                        moleculaA.colisionMismoTipo();
                }

            }
        }
    }

    public static void revisarColisionesH2O(ArrayList<MoleculaH2O> moleculasA){
        for (DibujadorMolecula moleculaA : moleculasA) {
            for (DibujadorMolecula moleculaB : moleculasA) {
                if (Posicion.checkColision(moleculaA.getPosicionInicial(), moleculaB.getPosicionInicial())) {
                    if(moleculaA!=moleculaB)
                        moleculaA.colisionMismoTipo();
                }

            }
        }
    }
}
